package com.hzy.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzy.infrastructure.Tools;
import com.hzy.infrastructure.domain.vo.PagingVo;
import com.hzy.infrastructure.exception.MessageBox;
import com.hzy.system.domain.*;
import com.hzy.system.domain.bo.AccountContext;
import com.hzy.system.domain.dto.SysMenuTreeDto;
import com.hzy.system.domain.dto.SysOrganizationTreeDto;
import com.hzy.system.domain.vo.*;
import com.hzy.system.mapper.ISysUserMapper;
import com.hzy.system.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 * +
 *
 * @author hzy
 * @since 2020-04-26
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<ISysUserMapper, SysUser> implements ISysUserService {

    private final ISysUserRoleService sysUserRoleService;
    private final ISysRoleService sysRoleService;
    private final IAccountService accountService;
    private final ISysMenuService sysMenuService;
    private final ISysUserPostService sysUserPostService;
    private final ISysPostService sysPostService;

    public SysUserServiceImpl(ISysUserRoleService sysUserRoleService, ISysRoleService sysRoleService, IAccountService accountService, ISysMenuService sysMenuService, ISysUserPostService sysUserPostService, ISysPostService sysPostService) {

        this.sysUserRoleService = sysUserRoleService;
        this.sysRoleService = sysRoleService;
        this.accountService = accountService;
        this.sysMenuService = sysMenuService;
        this.sysUserPostService = sysUserPostService;
        this.sysPostService = sysPostService;
    }

    /**
     * 查找列表
     *
     * @param page   page
     * @param size   size
     * @param search search
     * @return result
     */
    @Override
    public PagingVo<Map<String, Object>> findList(Integer page, Integer size, SysUser search) {
        Page<Map<String, Object>> iPage = new Page<>(page, size);
        List<Map<String, Object>> data = this.baseMapper.getList(iPage, search);
        return PagingVo.page(iPage, data);
    }

    /**
     * 根据 id 查询表单数据
     *
     * @param id id
     * @return result
     */
    @Override
    public Map<String, Object> findForm(String id) {
        Map<String, Object> map = new HashMap<>(10);

        SysUser form = this.baseMapper.selectById(id);
        form = Tools.nullSafe(form, new SysUser());
        //角色信息
        List<String> roleIds = this.sysUserRoleService.lambdaQuery()
                .eq(SysUserRole::getUserId, id)
                .select(SysUserRole::getRoleId)
                .list()
                .stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toList());
        List<SysRole> allRoleList = this.sysRoleService.lambdaQuery()
                .orderByAsc(SysRole::getNumber)
                .select(SysRole::getId, SysRole::getNumber, SysRole::getName)
                .list();
        //岗位信息
        List<String> postIds = this.sysUserPostService.lambdaQuery()
                .eq(SysUserPost::getUserId, id)
                .select(SysUserPost::getPostId)
                .list()
                .stream()
                .map(SysUserPost::getPostId)
                .collect(Collectors.toList());
        List<SysPost> allPostList = this.sysPostService.lambdaQuery()
                .orderByAsc(SysPost::getNumber)
                .list();
        //组装
        map.put("id", id);
        map.put("form", form);
        map.put("roleIds", roleIds);
        map.put("allRoleList", allRoleList);
        map.put("postIds", postIds);
        map.put("allPostList", allPostList);
        return map;
    }

    /**
     * 保存数据
     *
     * @param form form
     * @return result
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveForm(SysUserVo form) {
        SysUser model = form.getForm();
        List<String> roleIds = form.getRoleIds();

        // 如果是新增
        if (ObjectUtils.isEmpty(model.getId())) {
            model.setPassword(ObjectUtils.isEmpty(model.getPassword()) ? "123qwe" : model.getPassword());
        } else {
            if (ObjectUtils.isEmpty(model.getPassword())) {
                SysUser oldUser = this.baseMapper.selectById(model.getId());
                model.setPassword(oldUser.getPassword());
            } else {
                model.setPassword(model.getPassword());
            }
        }

        //验证账号是否存在
        if (this.baseMapper.exists(new LambdaQueryWrapper<SysUser>().eq(SysUser::getLoginName, model.getLoginName()).ne(SysUser::getId, model.getId()))) {
            MessageBox.show("登录账号名称已存在!");
        }

        boolean isSuccess = this.saveOrUpdate(model);
        if (!isSuccess) {
            MessageBox.show("操作失败!");
        }

        // 变更用户角色
        if (roleIds.size() > 0) {
            List<SysUserRole> oldUserRoleList = this.sysUserRoleService.lambdaQuery().eq(SysUserRole::getUserId, model.getId()).list();
            //删除旧的绑定数据
            this.sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, model.getId()));
            for (String item : roleIds) {
                SysUserRole userRole = oldUserRoleList.stream().filter(w -> item.equals(w.getRoleId())).findFirst().orElse(null);
                SysUserRole newUserRole = new SysUserRole();
                newUserRole.setId(userRole == null ? Tools.getUUID() : userRole.getId());
                newUserRole.setUserId(model.getId());
                newUserRole.setRoleId(item);
                this.sysUserRoleService.save(newUserRole);
            }
        }

        //处理岗位信息
        if (form.getPostIds().size() > 0) {
            List<SysUserPost> sysUserPosts = sysUserPostService.lambdaQuery().eq(SysUserPost::getUserId, model.getId()).list();
            //删除旧的绑定数据
            this.sysUserPostService.lambdaUpdate().eq(SysUserPost::getUserId, model.getId()).remove();
            for (String item : form.getPostIds()) {
                SysUserPost sysUserPost = sysUserPosts.stream().filter(w -> item.equals(w.getPostId())).findFirst().orElse(new SysUserPost());
                sysUserPost.setId(Tools.getUUID());
                sysUserPost.setPostId(item);
                sysUserPost.setUserId(model.getId());
                this.sysUserPostService.save(sysUserPost);
            }
        }

        return model.getId();
    }

    /**
     * 删除
     *
     * @param ids ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteList(List<String> ids) {
        for (String item : ids) {
            SysUser user = this.baseMapper.selectById(item);
            if (user.getIsDelete().equals(false)) {
                MessageBox.show("该信息不能删除！");
            }
            this.sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, item));
            this.removeById(item);
        }
    }

    /**
     * 获取用户和菜单信息
     *
     * @return result
     */
    @Override
    public AccountContext getUserAndMenuInfo() {
        AccountContext accountContext = this.accountService.getAccountContext();
        List<SysMenu> sysMenus = this.sysMenuService.getMenusByCurrentRole();
        //设置菜单 tree
        List<SysMenuTreeDto> sysMenuTreeDtos = this.sysMenuService.createMenus(0, sysMenus);
        accountContext.setMenus(sysMenuTreeDtos);
        //设置菜单权限
        accountContext.setMenuPowers(this.sysMenuService.getPowerByMenus(sysMenus));
        return accountContext;
    }

    @Override
    public List<Map<String, Object>> getSysOrganizationTree(List<SysOrganizationTreeDto> tree) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (SysOrganizationTreeDto item : tree) {
            Map<String, Object> map = new HashMap<>(3);
            map.put("key", item.getId());
            map.put("title", item.getName());
            map.put("children", item.getChildren().size() > 0 ? this.getSysOrganizationTree(item.getChildren()) : null);
            result.add(map);
        }

        return result;
    }

    @Override
    public boolean updateCurrentUser(SysUser form) {
        AccountContext accountInfo = this.accountService.getAccountContext();
        SysUser sysUser = this.getById(accountInfo.getId());
        sysUser.setName(form.getName());
        sysUser.setLoginName(form.getLoginName());
        sysUser.setEmail(form.getEmail());
        sysUser.setPhone(form.getPhone());
        return this.updateById(sysUser);
    }

}
